/**
 * Copyright 2019 吉鼎科技.

 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cn.easyplatform.web.task.zkex.listener;

import cn.easyplatform.lang.Strings;
import cn.easyplatform.messages.request.SimpleRequestMessage;
import cn.easyplatform.messages.vos.FieldUpdateVo;
import cn.easyplatform.messages.vos.datalist.ListFieldUpdateVo;
import cn.easyplatform.messages.vos.datalist.ListHeaderVo;
import cn.easyplatform.spi.service.ComponentService;
import cn.easyplatform.type.IResponseMessage;
import cn.easyplatform.type.ListRowVo;
import cn.easyplatform.web.contexts.Contexts;
import cn.easyplatform.web.dialog.MessageBox;
import cn.easyplatform.web.ext.zul.Checkgroup;
import cn.easyplatform.web.service.ServiceLocator;
import cn.easyplatform.web.task.zkex.ListSupport;
import cn.easyplatform.web.task.BackendException;
import cn.easyplatform.web.utils.PageUtils;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.InputEvent;
import org.zkoss.zkmax.zul.Chosenbox;
import org.zkoss.zul.Checkbox;
import org.zkoss.zul.Radiogroup;
import org.zkoss.zul.Selectbox;
import org.zkoss.zul.impl.InputElement;
import org.zkoss.zul.impl.NumberInputElement;


/**
 * @author <a href="mailto:davidchen@epclouds.com">littleDog</a> <br/>
 * @since 2.0.0 <br/>
 */
public class FieldUpdateEventListener implements EventListener<Event> {

    private ListSupport os;

    private ListHeaderVo header;

    private ListRowVo rv;

    private FieldUpdateEventListener(ListSupport os, ListHeaderVo header, ListRowVo rv) {
        this.os = os;
        this.header = header;
        this.rv = rv;
    }

    public final static boolean add(Component comp, ListSupport os,
                                    ListHeaderVo header, ListRowVo rv) {
        String eventName = null;
        if (comp instanceof InputElement)
            eventName = Events.ON_CHANGE;
        else if (comp instanceof Checkbox || comp instanceof Radiogroup
                || comp instanceof Checkgroup)
            eventName = Events.ON_CHECK;
        else if (comp instanceof Chosenbox || comp instanceof Selectbox)
            eventName = Events.ON_SELECT;
        if (eventName != null) {
            comp.addEventListener(eventName, new FieldUpdateEventListener(os,
                    header, rv));
            return true;
        }
        return false;
    }

    @Override
    public void onEvent(Event event) throws Exception {
        try {
            Contexts.setEvent(Event.class, event);
            ListFieldUpdateVo lfus = new ListFieldUpdateVo(os.getComponent().getId(),
                    os.isCustom() ? rv.getData() : rv.getKeys());
            String name = header.getField();
            if (Strings.isBlank(name))
                name = header.getName();
            Object value = PageUtils.getValue(event.getTarget(), false);
            lfus.addField(new FieldUpdateVo(name, value));
            SimpleRequestMessage req = new SimpleRequestMessage(os.getId(), lfus);
            IResponseMessage<?> resp = ServiceLocator.lookup(
                    ComponentService.class).fieldUpdate(req);
            if (!resp.isSuccess())
                throw new BackendException(resp);
            int index = os.getEntity().isShowRowNumbers() ? 1 : 0;
            for (ListHeaderVo that : os.getHeaders()) {
                if (that == header) {
                    if (rv.getData().length > index)
                        rv.getData()[index] = value;
                    break;
                }
                index++;
            }
            if (event.getTarget() instanceof NumberInputElement) {
                if (header.isTotal() && (event instanceof InputEvent)) {
                    InputEvent ie = (InputEvent) event;
                    NumberInputElement input = (NumberInputElement) event.getTarget();
                    Double val = ((Number) input.getRawValue()).doubleValue() - ((Number) ie.getPreviousValue()).doubleValue();
                    header.caculate(val.toString(), false);
                    os.refreshFoot();
                }
            }
        } catch (BackendException ex) {
            MessageBox.showMessage(ex.getMsg());
        } finally {
            Contexts.clear();
        }
    }
}
